/*Yipeng Huang and Scott Rogowski*/
/*yh2315 smr2167*/

//The combinatorial logic portion of the execute stage of the mips pipeline
module ExecuteStage (	pc_plus_four, read_value_0, read_value_1,

						//instruction words
						sign_extended, instruction_20_16, instruction_15_11,
						
						//execute stage controls
						ALU_source, ALU_op, register_destination,
						
						//outputs
						branch_address, ALU_result, ALU_zero, register_write_address
						
						);

	// data inputs
	input [31:0] pc_plus_four;
	input [31:0] read_value_0;
	input [31:0] read_value_1;
	
	// instruction words
	input [31:0] sign_extended;
	input [4:0] instruction_20_16;
	input [4:0] instruction_15_11;
	
	// execute stage controls
	input ALU_source;
	input [1:0] ALU_op;
	input register_destination;
	
	// outputs
	output [31:0] branch_address;
	output [31:0] ALU_result;
	output ALU_zero;
	output [4:0] register_write_address;
	
	// wires
	wire [31:0] shift_output;
	wire [31:0] ALU_input_1;

	// ALU Logic
	TwoToOneMultiplexer mux_1 (.mux_in_0(read_value_1), .mux_in_1(sign_extended), .selector(ALU_source), .mux_out(ALU_input_1)); //Multiplexer is controled by ALU_source
	ALU ALU (.ALU_input_0(read_value_0), .ALU_input_1(ALU_input_1), .ALU_op(ALU_op), .ALU_result(ALU_result), .ALU_zero(ALU_zero));

	// Branch Logic
	ShiftLeftTwo shift (.shift_input(sign_extended), .shift_output(shift_output));
	Adder branch_adder (.add_input_0(pc_plus_four), .add_input_1(shift_output), .add_result(branch_address));
	
	// Register Write Address Selector
	TwoToOneMultiplexer #(5) mux_2 (.mux_in_0(instruction_20_16), .mux_in_1(instruction_15_11), .selector(register_destination), .mux_out(register_write_address));
	
	endmodule